package cn.slipi.common.utils;

import com.google.common.collect.Lists;
import io.netty.buffer.UnpooledByteBufAllocator;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * Created by jone.wang on 2018/10/26.
 * Description:
 */
@SuppressWarnings("WeakerAccess")
public class LogUtils {

    public static final List<MediaType> legalLogMediaTypes = Lists.newArrayList(MediaType.TEXT_XML,
            MediaType.APPLICATION_XML,
            MediaType.APPLICATION_JSON,
            MediaType.APPLICATION_JSON_UTF8,
            MediaType.TEXT_PLAIN,
            MediaType.TEXT_XML);

    public static <T extends DataBuffer> T loggingRequest(Logger log, String headers, T body) {
        return logging(log, ">>>>>>>>>> Request ", headers, body);
    }

    public static void loggingRequest(Logger log, String headers, String queryParams) {
        logging(log, headers, queryParams);
    }

    public static <T extends DataBuffer> T loggingResponse(Logger log, String headers, T body) {
        return logging(log, "<<<<<<<<<< Response ", headers, body);
    }

    private static <T extends DataBuffer> T logging(Logger log, String inOrOut, String headers, T body) {
        try {
            InputStream dataBuffer = body.asInputStream();
            byte[] bytes = IOUtils.toByteArray(dataBuffer);
            NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false));
            String bodyStr = new String(bytes).replaceAll("\r|\n|\t", "");
            if (log.isDebugEnabled()) {
                log.debug("\n" + "{}Payload:\nheaders:[{}]\nbody:[{}]", inOrOut, headers, bodyStr);
            }
            DataBufferUtils.release(body);
            return (T) nettyDataBufferFactory.wrap(bytes);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    private static void logging(Logger log, String headers, String queryParams) {
        if (log.isDebugEnabled()) {
            log.debug("\n" + "{}Payload:\nheaders:[{}]\nqueryParams:[{}]", ">>>>>>>>>> Request ", headers, queryParams);
        }
    }
}